1 module unde.games.dizzy.omega.animations.explosure;
2 
3 import derelict.opengl3.gl;
4 import std.conv;
5 import std.format;
6 import std.math;
7 import unde.games.collision_detector;
8 import unde.games.dizzy.omega.dizzy;
9 import unde.games.dizzy.omega.main;
10 import unde.games.object;
11 import unde.games.renderer;
12 import unde.global_state;
13 
14 class Explosure:StaticGameObject
15 {
16     float x1, y1, z1;
17     float x2, y2, z2;
18 
19     LiveGameObject the_hero;
20     immutable float timer = 400.0;
21     
22     this(MainGameObject root, float[3] coords, float[3] coords1, float[3] coords2, LiveGameObject hero)
23     {
24         frame = -1;
25         x = coords[0];
26         y = coords[1];
27         z = coords[2];
28         
29         x1 = coords1[0];
30         y1 = coords1[1];
31         z1 = coords1[2];
32 
33         x2 = coords2[0];
34         y2 = coords2[1];
35         z2 = coords2[2];        
36         
37         models["platform2"] = root.models["platform2"];
38         models["before-explosure"] = root.models["before-explosure"];
39         models["after-explosure-up"] = root.models["after-explosure-up"];
40         models["after-explosure-down"] = root.models["after-explosure-down"];
41         models["bomb"] = root.models["bomb"];
42         models["explosure"] = root.models["explosure"];
43 
44         the_hero = hero;
45         super(root);
46     }
47 
48     override void draw(GlobalState gs)
49     {
50         if (abs(root.scrx-x) > 32.0 ||
51             abs(root.scry-y) > 18.0) return;
52             
53         DizzyOmega dz = cast(DizzyOmega) root;
54 
55         glPushMatrix();
56         if (frame < 0)
57         {
58             glTranslatef(x1, y1, z1);
59             recursive_render(gs, models["platform2"]);
60             
61             glPopMatrix();
62             glPushMatrix();
63 
64             glTranslatef(x, y, z);
65             recursive_render(gs, models["before-explosure"]);
66             
67             glPopMatrix();
68             glPushMatrix();
69 
70             glTranslatef(x2, y2, z2);
71             recursive_render(gs, models["bomb"]);
72         }
73         else
74         {
75             float f = frame;
76             if (f < timer)
77             {
78                 glTranslatef(x1, y1, z1);
79                 recursive_render(gs, models["platform2"]);
80                 
81                 glPopMatrix();
82                 glPushMatrix();
83     
84                 glTranslatef(x, y, z);
85                 recursive_render(gs, models["before-explosure"]);
86                 
87                 glPopMatrix();
88                 glPushMatrix();
89 
90                 glTranslatef(x2, y2, z2);
91                 recursive_render(gs, models["bomb"]);
92 
93                 glDisable(GL_LIGHTING);
94                 glTranslatef(-0.2, 0.0, 0.0);
95                 float f2 = f % 100.0;
96                 int num = cast(int)((timer - f)/100.0) + 1;
97 
98                 glScalef(f2/100.0, f2/100.0, f2/100.0);
99                 glTranslatef(2.2, 2.0, 0.0);
100         
101                 glBindTexture(GL_TEXTURE_2D, dz.textures["font"]);
102                 glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
103                 glEnable(GL_COLOR_MATERIAL);
104                 glColor4f(1.0, 1.0, 1.0, 1.0);
105                 print_text(format("%d", num));
106 
107                 glEnable(GL_LIGHTING);
108                 glDisable(GL_COLOR_MATERIAL);
109                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
110             }
111             else if (f < timer+100.0)
112             {
113                 glTranslatef(x1, y1, z1);
114                 recursive_render(gs, models["platform2"]);
115                 
116                 glPopMatrix();
117                 glPushMatrix();
118                 
119                 glTranslatef(x, y, z);
120                 recursive_render(gs, models["before-explosure"]);    
121                 
122                 glPopMatrix();
123                 glPushMatrix();
124 
125                 glTranslatef(x2, y2, z2);
126                 recursive_render(gs, models["bomb"]);
127                 glTranslatef(0.0, 0.0, -0.6);
128                 glScalef((f-timer)*2.0/100.0, (f-timer)*2.0/100.0, (f-timer)*2.0/100.0);
129                 recursive_render(gs, models["explosure"]);
130             }
131             else if (f < timer+200.0)
132             {
133                 glTranslatef(x1, y1, z1);
134                 recursive_render(gs, models["platform2"]);
135                 
136                 glPopMatrix();
137                 glPushMatrix();
138     
139                 glTranslatef(x, y, z);
140                 glRotatef((f-timer-100.0)*70.0/100.0, 0.0, 0.0, -1.0);
141                 recursive_render(gs, models["after-explosure-up"]);
142 
143                 glPopMatrix();
144                 glPushMatrix();
145     
146                 glTranslatef(x, y, z);
147                 recursive_render(gs, models["after-explosure-down"]);
148             }
149             else
150             {
151                 glTranslatef(x1, y1, z1);
152                 recursive_render(gs, models["platform2"]);
153                 
154                 glPopMatrix();
155                 glPushMatrix();
156     
157                 glTranslatef(x, y, z);
158                 glRotatef(70.0, 0.0, 0.0, -1.0);
159                 recursive_render(gs, models["after-explosure-up"]);
160 
161                 glPopMatrix();
162                 glPushMatrix();
163     
164                 glTranslatef(x, y, z);
165                 recursive_render(gs, models["after-explosure-down"]);
166             }
167         }
168         glPopMatrix();
169     }
170     
171     override bool tick(GlobalState gs)
172     {        
173         DizzyOmega dz = cast(DizzyOmega) root;
174 
175         long old_frame = frame;
176         if (frame >= 0)
177         {
178             int speedfactor = 1;
179 
180             if (frame < timer + 100)
181             {
182                 if (the_hero.y < -20.7 ||
183                     the_hero.y < -16.7 &&
184                      timer + 100 - frame < 200)
185                 {
186                     speedfactor = 1;
187                 }
188                 else if (the_hero.y < -16.7)
189                 {
190                     speedfactor = 2;
191                 }
192                 else
193                 {
194                     speedfactor = 4;
195                 }
196             }
197             
198             frame += speedfactor;
199         }
200         
201         if (frame < 0 && dz.baloon.inventory)
202         {
203             frame = 0;
204         }
205 
206         if (frame >= 0 &&
207             old_frame < cast(long) timer + 150 &&
208             frame >= cast(long) timer + 150)
209         {
210             dz.collision_objects["solid"]["BeforeExplosure1"] = null;
211             dz.collision_objects["solid"].remove("BeforeExplosure1");
212             dz.collision_objects["solid"]["BeforeExplosure2"] = null;
213             dz.collision_objects["solid"].remove("BeforeExplosure2");
214             
215             dz.collision_objects["solid"]["AfterExplosure1"] = 
216                 dz.collision_objects["temp-solid"]["AfterExplosure1"];
217             dz.collision_objects["solid"]["AfterExplosure2"] = 
218                 dz.collision_objects["temp-solid"]["AfterExplosure2"];
219 
220             reset_collision_cache();
221 
222             if (abs(dz.the_hero.x - 422.2) < 2.0 &&
223                 abs(dz.the_hero.y + 18.3) < 2.0 ||
224                 abs(dz.the_hero.x - 421.5) < 2.0 &&
225                 abs(dz.the_hero.y + 15.4) < 1.5)
226             {
227                 dz.the_hero.die("Rock");
228             }
229         }
230 
231         return true;
232     }
233 
234     override void load(string[string] s)
235     {
236         string p = "platform2";
237         if (p in s)
238             frame = s[p].to!(long);
239         else
240             frame = -1;
241 
242         DizzyOmega dz = cast(DizzyOmega) root;
243         if (frame < 0 || root.frame - frame < cast(long) timer + 150)
244         {
245             dz.collision_objects["solid"]["AfterExplosure1"] = null;
246             dz.collision_objects["solid"].remove("AfterExplosure1");
247             dz.collision_objects["solid"]["AfterExplosure2"] = null;
248             dz.collision_objects["solid"].remove("AfterExplosure2");
249 
250             dz.collision_objects["solid"]["BeforeExplosure1"] =
251                 dz.collision_objects["temp-solid"]["BeforeExplosure1"];
252             dz.collision_objects["solid"]["BeforeExplosure2"] =
253                 dz.collision_objects["temp-solid"]["BeforeExplosure2"];
254 
255             reset_collision_cache();
256         }
257         else
258         {
259             dz.collision_objects["solid"]["BeforeExplosure1"] = null;
260             dz.collision_objects["solid"].remove("BeforeExplosure1");
261             dz.collision_objects["solid"]["BeforeExplosure2"] = null;
262             dz.collision_objects["solid"].remove("BeforeExplosure2");
263             
264             dz.collision_objects["solid"]["AfterExplosure1"] = 
265                 dz.collision_objects["temp-solid"]["AfterExplosure1"];
266             dz.collision_objects["solid"]["AfterExplosure2"] = 
267                 dz.collision_objects["temp-solid"]["AfterExplosure2"];
268 
269             reset_collision_cache();
270         }
271     }
272 
273     override void save(ref string[string] s)
274     {
275         if (frame >= 0)
276         {
277             string p = "platform2";
278             s[p] = frame.to!(string);
279         }
280     }    
281 }